package maosy.oauth2.password.config

import com.google.gson.Gson
import com.google.gson.GsonBuilder
import maosy.oauth2.password.exception.ExistException
import maosy.oauth2.password.util.HttpEntityUtil
import maosy.oauth2.password.util.isFail
import maosy.oauth2.password.util.makeString
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ControllerAdvice
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.ResponseStatus
import javax.servlet.http.HttpServletRequest
import kotlin.math.max

@ControllerAdvice
class GlobalExceptionHandler {

    private val logger = LoggerFactory.getLogger(javaClass)
    private val gson = Gson()

    @ExceptionHandler(value = [ExistException::class])
    fun existExceptionHandler(req: HttpServletRequest, e: Exception): ResponseEntity<*> {
        return HttpEntityUtil.isFail(
            gson.toJson(
                mapOf(
                    "code" to 1005,
                    "message" to "${e.message}"
                )
            )
        )
    }

    @ExceptionHandler(value = [Exception::class])
    fun exceptionHandler(req: HttpServletRequest, e: Exception): ResponseEntity<*> {
        val errors = arrayListOf<String>()
        errors.add("request error:[uri] -> ${req.requestURI}")
        errors.add("request error:[message] -> ${e.message}")
        var maxLength = 0
        e.stackTrace.forEach {
            val err = "at ${it.className}.${it.methodName}(${it.fileName}:${it.lineNumber})"
            errors.add(err)
            if (err.length > maxLength) maxLength = err.length
        }
        val splitLine = String.makeString(maxLength, '*', "${e.message}")
        errors.add(0, splitLine)
        errors.add(String.makeString(splitLine.length, '*'))
        errors.forEach { logger.error(it) }
        return HttpEntityUtil.isFail(e.message)
    }
}